if (ret != 0)
return ret;
+ /* Domain 0 doesn't virtualize IO ports space. */
+ if (d == dom0)
+ return 0;
+
fp_offset = IO_SPACE_SPARSE_ENCODING(fp) & ~PAGE_MASK;
lp_offset = PAGE_ALIGN(IO_SPACE_SPARSE_ENCODING(lp));
return 0;
}
+static int
+ioports_has_allowed(struct domain *d, unsigned long fp, unsigned long lp)
+{
+ unsigned long i;
+ for (i = fp; i < lp; i++)
+ if (rangeset_contains_singleton(d->arch.ioport_caps, i))
+ return 1;
+ return 0;
+}
+
int
ioports_deny_access(struct domain *d, unsigned long fp, unsigned long lp)
{
for (off = fp_offset; off <= lp_offset; off += PAGE_SIZE) {
unsigned long mpaddr = IO_PORTS_PADDR + off;
+ unsigned long port;
volatile pte_t *pte;
pte_t old_pte;
+ port = IO_SPACE_SPARSE_DECODING (off);
+ if (port < fp || port + IO_SPACE_SPARSE_PORTS_PER_PAGE > lp) {
+ /* Maybe this covers an allowed port. */
+ if (ioports_has_allowed(d, port,
+ port + IO_SPACE_SPARSE_PORTS_PER_PAGE))
+ continue;
+ }
+
pte = lookup_noalloc_domain_pte_none(d, mpaddr);
BUG_ON(pte == NULL);
BUG_ON(pte_none(*pte));
#define IO_SPACE_SPARSE_ENCODING(p) ((((p) >> 2) << 12) | (p & 0xfff))
+#ifdef XEN
+/* Offset to IO port; do not catch error. */
+#define IO_SPACE_SPARSE_DECODING(off) ((((off) >> 12) << 2) | (off & 0x3))
+#define IO_SPACE_SPARSE_PORTS_PER_PAGE (0x4 << (PAGE_SHIFT - 12))
+#endif
+
struct io_space {
unsigned long mmio_base; /* base in MMIO space */
int sparse;